using System;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using HslCommunication.BasicFramework;
using HslCommunication.Core;
using HslCommunication.Core.Net;

namespace HslCommunication.Profinet.Keyence
{
	/// <summary>
	/// 基恩士KV上位链路串口通信的对象,适用于Nano系列串口数据,以及L20V通信模块，本类是基于tcp通信方式的类<br />
	/// Keyence KV upper link serial communication object, suitable for Nano series serial data and L20V communication module, this class is a class based on TCP communication method
	/// </summary>
	/// <remarks>
	/// 当读取Bool的输入的格式说明如下：
	/// <list type="table">
	///   <listheader>
	///     <term>地址名称</term>
	///     <term>地址代号</term>
	///     <term>示例</term>
	///     <term>地址范围</term>
	///     <term>备注</term>
	///   </listheader>
	///   <item>
	///     <term>继电器</term>
	///     <term>R</term>
	///     <term>R0,R100</term>
	///     <term>0-59915</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>控制继电器</term>
	///     <term>CR</term>
	///     <term>CR0,CR100</term>
	///     <term>0-3915</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>内部辅助继电器</term>
	///     <term>MR</term>
	///     <term>MR0,MR100</term>
	///     <term>0-99915</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>锁存继电器</term>
	///     <term>LR</term>
	///     <term>LR0,LR100</term>
	///     <term>0-99915</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>定时器</term>
	///     <term>T</term>
	///     <term>T0,T100</term>
	///     <term>0-3999</term>
	///     <term>通断</term>
	///   </item>
	///   <item>
	///     <term>计数器</term>
	///     <term>C</term>
	///     <term>C0,C100</term>
	///     <term>0-3999</term>
	///     <term>通断</term>
	///   </item>
	///   <item>
	///     <term>高速计数器</term>
	///     <term>CTH</term>
	///     <term>CTH0,CTH1</term>
	///     <term>0-1</term>
	///     <term>通断</term>
	///   </item>
	/// </list>
	/// 读取数据的地址如下：
	///
	/// <list type="table">
	///   <listheader>
	///     <term>地址名称</term>
	///     <term>地址代号</term>
	///     <term>示例</term>
	///     <term>地址范围</term>
	///     <term>备注</term>
	///   </listheader>
	///   <item>
	///     <term>数据存储器</term>
	///     <term>DM</term>
	///     <term>DM0,DM100</term>
	///     <term>0-65534</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>控制存储器</term>
	///     <term>CM</term>
	///     <term>CM0,CM100</term>
	///     <term>0-11998</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>临时数据存储器</term>
	///     <term>TM</term>
	///     <term>TM0,TM100</term>
	///     <term>0-511</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>扩展数据存储器</term>
	///     <term>EM</term>
	///     <term>EM0,EM100</term>
	///     <term>0-65534</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>扩展数据存储器</term>
	///     <term>FM</term>
	///     <term>FM0,FM100</term>
	///     <term>0-32766</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>变址寄存器</term>
	///     <term>Z</term>
	///     <term>Z1,Z5</term>
	///     <term>1-12</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>数字微调器</term>
	///     <term>AT</term>
	///     <term>AT0,AT5</term>
	///     <term>0-7</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>定时器</term>
	///     <term>T</term>
	///     <term>T0,T100</term>
	///     <term>0-3999</term>
	///     <term>当前值(current value), 读int</term>
	///   </item>
	///   <item>
	///     <term>计数器</term>
	///     <term>C</term>
	///     <term>C0,C100</term>
	///     <term>0-3999</term>
	///     <term>当前值(current value), 读int</term>
	///   </item>
	/// </list>
	/// </remarks>
	public class KeyenceNanoSerialOverTcp : NetworkDeviceSoloBase
	{
		/// <summary>
		/// 连接PLC的命令报文<br />
		/// Command message to connect to PLC
		/// </summary>
		public static byte[] ConnectCmd = new byte[3]
		{
			67,
			82,
			13
		};

		/// <summary>
		/// 断开PLC连接的命令报文<br />
		/// Command message to disconnect PLC
		/// </summary>
		public static byte[] DisConnectCmd = new byte[3]
		{
			67,
			81,
			13
		};

		/// <summary>
		/// 实例化一个默认的对象<br />
		/// Instantiate a default object
		/// </summary>
		public KeyenceNanoSerialOverTcp()
		{
			base.WordLength = 1;
			base.ByteTransform = new RegularByteTransform();
		}

		/// <summary>
		/// 使用指定的ip地址和端口号来初始化对象<br />
		/// Initialize the object with the specified IP address and port number
		/// </summary>
		/// <param name="ipAddress">Ip地址数据</param>
		/// <param name="port">端口号</param>
		public KeyenceNanoSerialOverTcp(string ipAddress, int port)
		{
			base.WordLength = 1;
			IpAddress = ipAddress;
			Port = port;
			base.ByteTransform = new RegularByteTransform();
		}

		/// <inheritdoc />
		protected override OperateResult InitializationOnConnect(Socket socket)
		{
			OperateResult<byte[]> operateResult = ReadFromCoreServer(socket, ConnectCmd);
			if (!operateResult.IsSuccess)
			{
				return operateResult;
			}
			return OperateResult.CreateSuccessResult();
		}

		/// <inheritdoc />
		protected override OperateResult ExtraOnDisconnect(Socket socket)
		{
			OperateResult<byte[]> operateResult = ReadFromCoreServer(socket, DisConnectCmd);
			if (!operateResult.IsSuccess)
			{
				return operateResult;
			}
			return OperateResult.CreateSuccessResult();
		}

		/// <inheritdoc />
		protected override async Task<OperateResult> InitializationOnConnectAsync(Socket socket)
		{
			OperateResult<byte[]> result = await ReadFromCoreServerAsync(socket, ConnectCmd);
			if (!result.IsSuccess)
			{
				return result;
			}
			return OperateResult.CreateSuccessResult();
		}

		/// <inheritdoc />
		protected override async Task<OperateResult> ExtraOnDisconnectAsync(Socket socket)
		{
			OperateResult<byte[]> result = await ReadFromCoreServerAsync(socket, DisConnectCmd);
			if (!result.IsSuccess)
			{
				return result;
			}
			return OperateResult.CreateSuccessResult();
		}

		/// <inheritdoc />
		public override OperateResult<byte[]> Read(string address, ushort length)
		{
			OperateResult<byte[]> operateResult = BuildReadCommand(address, length);
			if (!operateResult.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(operateResult);
			}
			OperateResult<byte[]> operateResult2 = ReadFromCoreServer(operateResult.Content);
			if (!operateResult2.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(operateResult2);
			}
			OperateResult operateResult3 = CheckPlcReadResponse(operateResult2.Content);
			if (!operateResult3.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(operateResult3);
			}
			OperateResult<string, int> operateResult4 = KvAnalysisAddress(address);
			if (!operateResult4.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(operateResult4);
			}
			return ExtractActualData(operateResult4.Content1, operateResult2.Content);
		}

		/// <inheritdoc />
		public override OperateResult Write(string address, byte[] value)
		{
			OperateResult<byte[]> operateResult = BuildWriteCommand(address, value);
			if (!operateResult.IsSuccess)
			{
				return operateResult;
			}
			OperateResult<byte[]> operateResult2 = ReadFromCoreServer(operateResult.Content);
			if (!operateResult2.IsSuccess)
			{
				return operateResult2;
			}
			OperateResult operateResult3 = CheckPlcWriteResponse(operateResult2.Content);
			if (!operateResult3.IsSuccess)
			{
				return operateResult3;
			}
			return OperateResult.CreateSuccessResult();
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Keyence.KeyenceNanoSerialOverTcp.Read(System.String,System.UInt16)" />
		public override async Task<OperateResult<byte[]>> ReadAsync(string address, ushort length)
		{
			OperateResult<byte[]> command = BuildReadCommand(address, length);
			if (!command.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(command);
			}
			OperateResult<byte[]> read = await ReadFromCoreServerAsync(command.Content);
			if (!read.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(read);
			}
			OperateResult ackResult = CheckPlcReadResponse(read.Content);
			if (!ackResult.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(ackResult);
			}
			OperateResult<string, int> addressResult = KvAnalysisAddress(address);
			if (!addressResult.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(addressResult);
			}
			return ExtractActualData(addressResult.Content1, read.Content);
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Keyence.KeyenceNanoSerialOverTcp.Write(System.String,System.Byte[])" />
		public override async Task<OperateResult> WriteAsync(string address, byte[] value)
		{
			OperateResult<byte[]> command = BuildWriteCommand(address, value);
			if (!command.IsSuccess)
			{
				return command;
			}
			OperateResult<byte[]> read = await ReadFromCoreServerAsync(command.Content);
			if (!read.IsSuccess)
			{
				return read;
			}
			OperateResult checkResult = CheckPlcWriteResponse(read.Content);
			if (!checkResult.IsSuccess)
			{
				return checkResult;
			}
			return OperateResult.CreateSuccessResult();
		}

		/// <inheritdoc />
		public override OperateResult<bool[]> ReadBool(string address, ushort length)
		{
			OperateResult<byte[]> operateResult = BuildReadCommand(address, length);
			if (!operateResult.IsSuccess)
			{
				return OperateResult.CreateFailedResult<bool[]>(operateResult);
			}
			OperateResult<byte[]> operateResult2 = ReadFromCoreServer(operateResult.Content);
			if (!operateResult2.IsSuccess)
			{
				return OperateResult.CreateFailedResult<bool[]>(operateResult2);
			}
			OperateResult operateResult3 = CheckPlcReadResponse(operateResult2.Content);
			if (!operateResult3.IsSuccess)
			{
				return OperateResult.CreateFailedResult<bool[]>(operateResult3);
			}
			OperateResult<string, int> operateResult4 = KvAnalysisAddress(address);
			if (!operateResult4.IsSuccess)
			{
				return OperateResult.CreateFailedResult<bool[]>(operateResult4);
			}
			return ExtractActualBoolData(operateResult4.Content1, operateResult2.Content);
		}

		/// <inheritdoc />
		public override OperateResult Write(string address, bool value)
		{
			OperateResult<byte[]> operateResult = BuildWriteCommand(address, value);
			if (!operateResult.IsSuccess)
			{
				return operateResult;
			}
			OperateResult<byte[]> operateResult2 = ReadFromCoreServer(operateResult.Content);
			if (!operateResult2.IsSuccess)
			{
				return operateResult2;
			}
			OperateResult operateResult3 = CheckPlcWriteResponse(operateResult2.Content);
			if (!operateResult3.IsSuccess)
			{
				return operateResult3;
			}
			return OperateResult.CreateSuccessResult();
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Keyence.KeyenceNanoSerialOverTcp.ReadBool(System.String,System.UInt16)" />
		public override async Task<OperateResult<bool[]>> ReadBoolAsync(string address, ushort length)
		{
			OperateResult<byte[]> command = BuildReadCommand(address, length);
			if (!command.IsSuccess)
			{
				return OperateResult.CreateFailedResult<bool[]>(command);
			}
			OperateResult<byte[]> read = await ReadFromCoreServerAsync(command.Content);
			if (!read.IsSuccess)
			{
				return OperateResult.CreateFailedResult<bool[]>(read);
			}
			OperateResult ackResult = CheckPlcReadResponse(read.Content);
			if (!ackResult.IsSuccess)
			{
				return OperateResult.CreateFailedResult<bool[]>(ackResult);
			}
			OperateResult<string, int> addressResult = KvAnalysisAddress(address);
			if (!addressResult.IsSuccess)
			{
				return OperateResult.CreateFailedResult<bool[]>(addressResult);
			}
			return ExtractActualBoolData(addressResult.Content1, read.Content);
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Keyence.KeyenceNanoSerialOverTcp.Write(System.String,System.Boolean)" />
		public override async Task<OperateResult> WriteAsync(string address, bool value)
		{
			OperateResult<byte[]> command = BuildWriteCommand(address, value);
			if (!command.IsSuccess)
			{
				return command;
			}
			OperateResult<byte[]> read = await ReadFromCoreServerAsync(command.Content);
			if (!read.IsSuccess)
			{
				return read;
			}
			OperateResult checkResult = CheckPlcWriteResponse(read.Content);
			if (!checkResult.IsSuccess)
			{
				return checkResult;
			}
			return OperateResult.CreateSuccessResult();
		}

		/// <inheritdoc />
		public override string ToString()
		{
			return $"KeyenceNanoSerialOverTcp[{IpAddress}:{Port}]";
		}

		/// <summary>
		/// 建立读取PLC数据的指令，需要传入地址数据，以及读取的长度，地址示例参照类的说明文档<br />
		/// To create a command to read PLC data, you need to pass in the address data, and the length of the read. For an example of the address, refer to the class documentation
		/// </summary>
		/// <param name="address">软元件地址</param>
		/// <param name="length">读取长度</param>
		/// <returns>是否建立成功</returns>
		public static OperateResult<byte[]> BuildReadCommand(string address, ushort length)
		{
			OperateResult<string, int> operateResult = KvAnalysisAddress(address);
			if (!operateResult.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(operateResult);
			}
			if ((operateResult.Content1 == "CTH" || operateResult.Content1 == "CTC" || operateResult.Content1 == "C" || operateResult.Content1 == "T") && length > 1)
			{
				length = (ushort)((int)length / 2);
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("RDS");
			stringBuilder.Append(" ");
			stringBuilder.Append(operateResult.Content1);
			stringBuilder.Append(operateResult.Content2.ToString());
			stringBuilder.Append(" ");
			stringBuilder.Append(length.ToString());
			stringBuilder.Append("\r");
			byte[] bytes = Encoding.ASCII.GetBytes(stringBuilder.ToString());
			return OperateResult.CreateSuccessResult(bytes);
		}

		/// <summary>
		/// 建立写入PLC数据的指令，需要传入地址数据，以及写入的数据信息，地址示例参照类的说明文档<br />
		/// To create a command to write PLC data, you need to pass in the address data and the written data information. For an example of the address, refer to the class documentation
		/// </summary>
		/// <param name="address">软元件地址</param>
		/// <param name="value">转换后的数据</param>
		/// <returns>是否成功的信息</returns>
		public static OperateResult<byte[]> BuildWriteCommand(string address, byte[] value)
		{
			OperateResult<string, int> operateResult = KvAnalysisAddress(address);
			if (!operateResult.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(operateResult);
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("WRS");
			stringBuilder.Append(" ");
			stringBuilder.Append(operateResult.Content1);
			stringBuilder.Append(operateResult.Content2);
			stringBuilder.Append(" ");
			if (operateResult.Content1 == "DM" || operateResult.Content1 == "CM" || operateResult.Content1 == "TM" || operateResult.Content1 == "EM" || operateResult.Content1 == "FM" || operateResult.Content1 == "Z")
			{
				int num = value.Length / 2;
				stringBuilder.Append(num.ToString());
				stringBuilder.Append(" ");
				for (int i = 0; i < num; i++)
				{
					stringBuilder.Append(BitConverter.ToUInt16(value, i * 2));
					if (i != num - 1)
					{
						stringBuilder.Append(" ");
					}
				}
			}
			else if (operateResult.Content1 == "T" || operateResult.Content1 == "C" || operateResult.Content1 == "CTH")
			{
				int num2 = value.Length / 4;
				stringBuilder.Append(num2.ToString());
				stringBuilder.Append(" ");
				for (int j = 0; j < num2; j++)
				{
					stringBuilder.Append(BitConverter.ToUInt32(value, j * 4));
					if (j != num2 - 1)
					{
						stringBuilder.Append(" ");
					}
				}
			}
			stringBuilder.Append("\r");
			return OperateResult.CreateSuccessResult(Encoding.ASCII.GetBytes(stringBuilder.ToString()));
		}

		/// <summary>
		/// 建立写入bool数据的指令，针对地址类型为 R,CR,MR,LR<br />
		/// Create instructions to write bool data, address type is R, CR, MR, LR
		/// </summary>
		/// <param name="address">软元件地址</param>
		/// <param name="value">转换后的数据</param>
		/// <returns>是否成功的信息</returns>
		public static OperateResult<byte[]> BuildWriteCommand(string address, bool value)
		{
			OperateResult<string, int> operateResult = KvAnalysisAddress(address);
			if (!operateResult.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(operateResult);
			}
			StringBuilder stringBuilder = new StringBuilder();
			if (value)
			{
				stringBuilder.Append("ST");
			}
			else
			{
				stringBuilder.Append("RS");
			}
			stringBuilder.Append(" ");
			stringBuilder.Append(operateResult.Content1);
			stringBuilder.Append(operateResult.Content2);
			stringBuilder.Append("\r");
			return OperateResult.CreateSuccessResult(Encoding.ASCII.GetBytes(stringBuilder.ToString()));
		}

		/// <summary>
		/// 校验读取返回数据状态，主要返回的第一个字节是不是E<br />
		/// Check the status of the data returned from reading, whether the first byte returned is E
		/// </summary>
		/// <param name="ack">反馈信息</param>
		/// <returns>是否成功的信息</returns>
		public static OperateResult CheckPlcReadResponse(byte[] ack)
		{
			if (ack.Length == 0)
			{
				return new OperateResult(StringResources.Language.MelsecFxReceiveZero);
			}
			if (ack[0] == 69)
			{
				return new OperateResult(StringResources.Language.MelsecFxAckWrong + " Actual: " + Encoding.ASCII.GetString(ack));
			}
			if (ack[ack.Length - 1] != 10 && ack[ack.Length - 2] != 13)
			{
				return new OperateResult(StringResources.Language.MelsecFxAckWrong + " Actual: " + SoftBasic.ByteToHexString(ack, ' '));
			}
			return OperateResult.CreateSuccessResult();
		}

		/// <summary>
		/// 校验写入返回数据状态，检测返回的数据是不是OK<br />
		/// Verify the status of the returned data written and check whether the returned data is OK
		/// </summary>
		/// <param name="ack">反馈信息</param>
		/// <returns>是否成功的信息</returns>
		public static OperateResult CheckPlcWriteResponse(byte[] ack)
		{
			if (ack.Length == 0)
			{
				return new OperateResult(StringResources.Language.MelsecFxReceiveZero);
			}
			if (ack[0] == 79 && ack[1] == 75)
			{
				return OperateResult.CreateSuccessResult();
			}
			return new OperateResult(StringResources.Language.MelsecFxAckWrong + " Actual: " + SoftBasic.ByteToHexString(ack, ' '));
		}

		/// <summary>
		/// 从PLC反馈的数据进行提炼Bool操作<br />
		/// Refine Bool operation from data fed back from PLC
		/// </summary>
		/// <param name="addressType">地址的数据类型</param>
		/// <param name="response">PLC反馈的真实数据</param>
		/// <returns>数据提炼后的真实数据</returns>
		public static OperateResult<bool[]> ExtractActualBoolData(string addressType, byte[] response)
		{
			try
			{
				string @string = Encoding.Default.GetString(response.RemoveLast(2));
				int num;
				switch (addressType)
				{
				default:
					num = ((addressType == "LR") ? 1 : 0);
					break;
				case "R":
				case "CR":
				case "MR":
					num = 1;
					break;
				}
				if (num != 0)
				{
					return OperateResult.CreateSuccessResult((from m in @string.Split(new char[1]
						{
							' '
						}, StringSplitOptions.RemoveEmptyEntries)
						select m == "1").ToArray());
				}
				int num2;
				switch (addressType)
				{
				default:
					num2 = ((addressType == "CTC") ? 1 : 0);
					break;
				case "T":
				case "C":
				case "CTH":
					num2 = 1;
					break;
				}
				if (num2 != 0)
				{
					return OperateResult.CreateSuccessResult((from m in @string.Split(new char[1]
						{
							' '
						}, StringSplitOptions.RemoveEmptyEntries)
						select m.StartsWith("1")).ToArray());
				}
				return new OperateResult<bool[]>(StringResources.Language.NotSupportedDataType);
			}
			catch (Exception ex)
			{
				OperateResult<bool[]> operateResult = new OperateResult<bool[]>();
				operateResult.Message = "Extract Msg：" + ex.Message + Environment.NewLine + "Data: " + SoftBasic.ByteToHexString(response);
				return operateResult;
			}
		}

		/// <summary>
		/// 从PLC反馈的数据进行提炼操作<br />
		/// Refining operation from data fed back from PLC
		/// </summary>
		/// <param name="addressType">地址的数据类型</param>
		/// <param name="response">PLC反馈的真实数据</param>
		/// <returns>数据提炼后的真实数据</returns>
		public static OperateResult<byte[]> ExtractActualData(string addressType, byte[] response)
		{
			try
			{
				string @string = Encoding.Default.GetString(response.RemoveLast(2));
				string[] array = @string.Split(new char[1]
				{
					' '
				}, StringSplitOptions.RemoveEmptyEntries);
				int num;
				switch (addressType)
				{
				default:
					num = ((addressType == "Z") ? 1 : 0);
					break;
				case "DM":
				case "CM":
				case "TM":
				case "EM":
				case "FM":
					num = 1;
					break;
				}
				if (num != 0)
				{
					byte[] array2 = new byte[array.Length * 2];
					for (int i = 0; i < array.Length; i++)
					{
						BitConverter.GetBytes(ushort.Parse(array[i])).CopyTo(array2, i * 2);
					}
					return OperateResult.CreateSuccessResult(array2);
				}
				int num2;
				switch (addressType)
				{
				case "AT":
				{
					byte[] array3 = new byte[array.Length * 4];
					for (int j = 0; j < array.Length; j++)
					{
						BitConverter.GetBytes(uint.Parse(array[j])).CopyTo(array3, j * 4);
					}
					return OperateResult.CreateSuccessResult(array3);
				}
				default:
					num2 = ((addressType == "CTC") ? 1 : 0);
					break;
				case "T":
				case "C":
				case "CTH":
					num2 = 1;
					break;
				}
				if (num2 != 0)
				{
					byte[] array4 = new byte[array.Length * 4];
					for (int k = 0; k < array.Length; k++)
					{
						string[] array5 = array[k].Split(new char[1]
						{
							','
						}, StringSplitOptions.RemoveEmptyEntries);
						BitConverter.GetBytes(uint.Parse(array5[1])).CopyTo(array4, k * 4);
					}
					return OperateResult.CreateSuccessResult(array4);
				}
				return new OperateResult<byte[]>(StringResources.Language.NotSupportedDataType);
			}
			catch (Exception ex)
			{
				OperateResult<byte[]> operateResult = new OperateResult<byte[]>();
				operateResult.Message = "Extract Msg：" + ex.Message + Environment.NewLine + "Data: " + SoftBasic.ByteToHexString(response);
				return operateResult;
			}
		}

		/// <summary>
		/// 解析数据地址成不同的Keyence地址类型<br />
		/// Parse data addresses into different keyence address types
		/// </summary>
		/// <param name="address">数据地址</param>
		/// <returns>地址结果对象</returns>
		public static OperateResult<string, int> KvAnalysisAddress(string address)
		{
			try
			{
				if (address.StartsWith("CTH") || address.StartsWith("cth"))
				{
					return OperateResult.CreateSuccessResult("CTH", int.Parse(address.Substring(3)));
				}
				if (address.StartsWith("CTC") || address.StartsWith("ctc"))
				{
					return OperateResult.CreateSuccessResult("CTC", int.Parse(address.Substring(3)));
				}
				if (address.StartsWith("CR") || address.StartsWith("cr"))
				{
					return OperateResult.CreateSuccessResult("CR", int.Parse(address.Substring(2)));
				}
				if (address.StartsWith("MR") || address.StartsWith("mr"))
				{
					return OperateResult.CreateSuccessResult("MR", int.Parse(address.Substring(2)));
				}
				if (address.StartsWith("LR") || address.StartsWith("lr"))
				{
					return OperateResult.CreateSuccessResult("LR", int.Parse(address.Substring(2)));
				}
				if (address.StartsWith("DM") || address.StartsWith("DM"))
				{
					return OperateResult.CreateSuccessResult("DM", int.Parse(address.Substring(2)));
				}
				if (address.StartsWith("CM") || address.StartsWith("cm"))
				{
					return OperateResult.CreateSuccessResult("CM", int.Parse(address.Substring(2)));
				}
				if (address.StartsWith("TM") || address.StartsWith("tm"))
				{
					return OperateResult.CreateSuccessResult("TM", int.Parse(address.Substring(2)));
				}
				if (address.StartsWith("EM") || address.StartsWith("em"))
				{
					return OperateResult.CreateSuccessResult("EM", int.Parse(address.Substring(2)));
				}
				if (address.StartsWith("FM") || address.StartsWith("fm"))
				{
					return OperateResult.CreateSuccessResult("FM", int.Parse(address.Substring(2)));
				}
				if (address.StartsWith("AT") || address.StartsWith("at"))
				{
					return OperateResult.CreateSuccessResult("AT", int.Parse(address.Substring(2)));
				}
				if (address.StartsWith("Z") || address.StartsWith("z"))
				{
					return OperateResult.CreateSuccessResult("Z", int.Parse(address.Substring(1)));
				}
				if (address.StartsWith("R") || address.StartsWith("r"))
				{
					return OperateResult.CreateSuccessResult("", int.Parse(address.Substring(1)));
				}
				if (address.StartsWith("T") || address.StartsWith("t"))
				{
					return OperateResult.CreateSuccessResult("T", int.Parse(address.Substring(1)));
				}
				if (address.StartsWith("C") || address.StartsWith("c"))
				{
					return OperateResult.CreateSuccessResult("C", int.Parse(address.Substring(1)));
				}
				throw new Exception(StringResources.Language.NotSupportedDataType);
			}
			catch (Exception ex)
			{
				return new OperateResult<string, int>(ex.Message);
			}
		}
	}
}
